/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.yczbj.ycvideoplayer.ability;

import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;
import ohos.agp.components.StackLayout;
import ohos.app.Context;
import ohos.bundle.AbilityInfo;

import com.yc.video.config.ConstantKeys;
import com.yc.video.config.VideoInfoBean;
import com.yc.video.player.SimpleStateListener;
import com.yc.video.player.VideoPlayer;
import com.yc.video.player.VideoViewManager;
import com.yc.video.tool.PlayerUtils;
import com.yc.video.ui.view.BasisVideoController;

import org.yczbj.ycvideoplayer.ResourceTable;
import org.yczbj.ycvideoplayer.adapter.VideoRecyclerViewAdapter;
import org.yczbj.ycvideoplayer.fraction.OnItemChildClickListener;

import java.util.ArrayList;
import java.util.List;

/**
 * 模仿抖音短视频，使用RecyclerView，实现了预加载功能
 *
 * @since 2021-05-12
 */
public class TikTok1Ability extends BaseAbility {
    private static final String KEY_INDEX = "index";
    protected List<VideoInfoBean> mVideos = new ArrayList<>();
    protected VideoRecyclerViewAdapter mAdapter;
    protected ListContainer mRecyclerView;
    protected VideoPlayer mVideoView;

    /**
     * 当前播放的位置
     */
    protected int mCurPos = -1;
    /**
     * 上次播放的位置，用于页面切回来之后恢复播放
     */
    protected int mLastPos = mCurPos;

    /**
     * 启动
     *
     * @param context 上下文
     * @param index 指标
     */
    public static void start(Context context, int index) {
        Intent intent = new Intent();
        intent.setOperation(new Intent.OperationBuilder()
            .withBundleName(context.getBundleName())
            .withAbilityName(TikTok2Ability.class.getName())
            .build());
        intent.setParam(KEY_INDEX, index);
        context.startAbility(intent, 0);
    }

    @Override
    protected int getLayoutResId() {
        return ResourceTable.Layout_base_recycler_view;
    }

    @Override
    protected void initComponent(Intent intent) {
        mCurPos = getIntent().getIntParam(KEY_INDEX, 0);
        initVideoView();
        mRecyclerView = (ListContainer) findComponentById(ResourceTable.Id_recyclerView);
        mRecyclerView.setOrientation(Component.VERTICAL);
        mAdapter = new VideoRecyclerViewAdapter(mVideos);
        mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
            @Override
            public void onItemChildClick(int position) {
                startPlay(position);
            }
        });
        mRecyclerView.setItemProvider(mAdapter);
        mRecyclerView.addItemVisibilityChangedListener(new ListContainer.ItemVisibilityChangedListener() {
            @Override
            public void onItemAdded(Component component, int i) {
            }

            @Override
            public void onItemRemoved(Component component, int i) {
                StackLayout playerContainer = (StackLayout) component
                    .findComponentById(ResourceTable.Id_player_container);
                Component v = playerContainer.getComponentAt(0);
                if (v != null && v == mVideoView && !mVideoView.isFullScreen()) {
                    releaseVideoView();
                }
            }
        });
    }

    /**
     * 初始化视图
     */
    protected void initVideoView() {
        mVideoView = new VideoPlayer(this);
        mVideoView.setOnStateChangeListener(new SimpleStateListener() {
            @Override
            public void onPlayStateChanged(int playState) {
                // 监听VideoViewManager释放，重置状态
                if (playState == ConstantKeys.CurrentState.STATE_IDLE) {
                    PlayerUtils.removeViewFormParent(mVideoView);
                    mLastPos = mCurPos;
                    mCurPos = -1;
                }
            }
        });
        mController = new BasisVideoController(this);
        mVideoView.setController(mController);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        pause();
    }

    /**
     * 由于onPause必须调用super。故增加此方法，
     * 子类将会重写此方法，改变onPause的逻辑
     */
    protected void pause() {
        releaseVideoView();
    }

    @Override
    protected void onActive() {
        super.onActive();
        resume();
    }

    /**
     * 由于onResume必须调用super。故增加此方法，
     * 子类将会重写此方法，改变onResume的逻辑
     */
    protected void resume() {
        if (mLastPos == -1) {
            return;
        }

        // 恢复上次播放的位置
        startPlay(mLastPos);
    }

    /**
     * 开始播放
     *
     * @param position 列表位置
     */
    protected void startPlay(int position) {
        if (mCurPos == position) {
            return;
        }
        if (mCurPos != -1) {
            releaseVideoView();
        }
        VideoInfoBean videoBean = mVideos.get(position);
        mVideoView.setUrl(videoBean.getVideoUrl());
        Component itemView = mRecyclerView.getComponentAt(position);
        if (itemView == null) {
            return;
        }
        VideoRecyclerViewAdapter.Holder viewHolder = (VideoRecyclerViewAdapter.Holder) itemView.getTag();
        // 把列表中预置的PrepareView添加到控制器中，注意isPrivate此处只能为true。
        mController.addControlComponent(viewHolder.mPrepareView, true);
        PlayerUtils.removeViewFormParent(mVideoView);
        viewHolder.mPlayerContainer.addComponent(mVideoView, 0);
        // 播放之前将VideoView添加到VideoViewManager以便在别的页面也能操作它
        VideoViewManager.instance().add(mVideoView, "list");
        mVideoView.start();
        mCurPos = position;
    }

    private void releaseVideoView() {
        mVideoView.release();
        if (mVideoView.isFullScreen()) {
            mVideoView.stopFullScreen();
        }
        if (this.getDisplayOrientation() != 1) {
            this.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
        }
        mCurPos = -1;
    }
}
